package openase.audio;

public abstract class Storage {

	/**
	 * Configures the storage to be used.
	 * 
	 * @param storage
	 *            the storage to be used.
	 */
	public static void setStorage(Storage storage) {
		synchronized (Storage.class) {
			storageInstance = storage;
		}
	}

	private static volatile Storage storageInstance;

	public static Storage getStorage() {
		if (storageInstance == null) {
			synchronized (Storage.class) {
				if (storageInstance == null) {
					storageInstance = newStorage();
				}
			}
		}
		return storageInstance;
	}

	private static Storage newStorage() {
		return new MemoryStorage();
	}

	protected Storage() {
	}

	public final AudioInfo newAudio(String name) {
		return new AudioInfo(name);
	}

	protected final AudioInfo newAudio(int id, String name) {
		return new AudioInfo(id, name);
	}

	public final AudioFingerprint newFingerprint(AudioInfo source, int offset, long hash) {
		return new AudioFingerprint(source, offset, hash);
	}

	public final AudioFingerprint newFingerprint(int offset, long hash) {
		return newFingerprint(null, offset, hash);
	}

	public abstract AudioInfo getAudio(int id) throws StorageException;

	public abstract AudioInfo getAudio(String name) throws StorageException;

	public abstract void addFingerprint(AudioFingerprint fingerprint) throws StorageException;

	public abstract void addAudio(AudioInfo audio) throws StorageException;

	public abstract int getAudioCount() throws StorageException;

	public abstract int getFingerprintCount() throws StorageException;

	public abstract int getFingerprintCount(AudioInfo audio) throws StorageException;

	public abstract AudioFingerprint[] getMatchingFingerprints(long hash) throws StorageException;

}
